package com.ultimatech.webappdemo.authmgr.service.impl;

import com.ultimatech.webappdemo.authmgr.dao.IAuthDao;
import com.ultimatech.webappdemo.authmgr.service.IAuthService;
import com.ultimatech.webappdemo.authmgr.service.IPasswordService;
import com.ultimatech.webappdemo.authmgr.vo.*;
import com.ultimatech.webappdemo.base.AuthcType;
import com.ultimatech.webappdemo.base.GroupRolePrefix;
import com.ultimatech.webappdemo.base.GroupState;
import com.ultimatech.webappdemo.base.PageResult;
import com.ultimatech.webappdemo.base.model.*;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Created by 张乐平 on 7/28 0028.
 */
@Service("authSvr")
public class AuthServiceImpl implements IAuthService {

    @Autowired
    private IPasswordService passwordService;

    public IAuthDao getAuthDao() {
        return authDao;
    }

    public void setAuthDao(IAuthDao authDao) {
        this.authDao = authDao;
    }

    @Autowired
    private IAuthDao authDao;

    public void logIn(String userName, String password, boolean rememberMe) throws AuthenticationException {
        UsernamePasswordToken token = new UsernamePasswordToken(userName, password);
        token.setRememberMe(rememberMe);
        SecurityUtils.getSubject().login(token);
    }

    public void logOut() {
        SecurityUtils.getSubject().logout();
    }

    public List<SysAuthcMap> getFilterChainDefinitions() {
        return this.getAuthDao().getAllAuthcMap();
    }

    public PageResult<SysUser> getUserList(UserVo vo) {
        return this.getAuthDao().getAllUsers(vo);
    }

    public List<SysRole> getAllRoles() {
        return this.getAuthDao().getAllRoles();
    }

    public void createUser(AddUserVo vo) throws Exception {
        SysUser u = this.getAuthDao().findByName(vo.getAddUserName());
        if (u != null) {
            throw new Exception("用户名重复！");
        }
        if ("".equals(vo.getPassword())) {
            throw new Exception("密码不能为空！");
        }
        if ("".equals(vo.getPassword2())) {
            throw new Exception("请确认密码！");
        }
        if (vo.getRoles() == null) {
            throw new Exception("请为用户分配角色！");
        }
        SysUser user = new SysUser();
        user.setUsername(vo.getAddUserName());
        user.setPassword(passwordService.encrypt(vo.getPassword()));
        user.setCreateTime(new Date());
        if (vo.getRoles() != null) {
            user.setRoleList(new ArrayList<SysRole>());
            for (String roleName : vo.getRoles()) {
                SysRole role = this.getAuthDao().findRoleByName(roleName);
                user.getRoleList().add(role);
            }
        }
        this.getAuthDao().saveOrUpdateUser(user);
    }

    public void delUser(Integer userId) {
        SysUser user = this.getAuthDao().findUserById(userId);
        this.getAuthDao().delUser(user);
    }

    public AddUserVo getUserById(Integer userId) {
        SysUser u = this.getAuthDao().findUserById(userId);
        if (u != null) {
            AddUserVo vo = new AddUserVo();
            vo.setUserId(u.getId());
            vo.setPassword(u.getPassword());
            vo.setAddUserName(u.getUsername());
            vo.setPassword2(u.getPassword());
            List<SysRole> roles = u.getRoleList();
            List<String> stringList = new ArrayList<String>();
            for (SysRole role : roles) {
                stringList.add(role.getRolename());
            }
            vo.setRoles(stringList.toArray(new String[stringList.size()]));
            return vo;
        } else {
            return null;
        }
    }

    public void modifyUser(AddUserVo vo) throws Exception {
        SysUser u = this.getAuthDao().findByName(vo.getAddUserName());
        if (u != null && !u.getId().equals(vo.getUserId())) {
            throw new Exception("用户名重复！");
        }
        if ("".equals(vo.getPassword())) {
            throw new Exception("密码不能为空！");
        }
        if ("".equals(vo.getPassword2())) {
            throw new Exception("请确认密码！");
        }
        if (vo.getRoles() == null) {
            throw new Exception("请为用户分配角色！");
        }
        SysUser user = this.getAuthDao().findUserById(vo.getUserId());
        user.setUsername(vo.getAddUserName());
        user.setPassword(passwordService.encrypt(vo.getPassword()));
        if (vo.getRoles() != null) {
            user.setRoleList(new ArrayList<SysRole>());
            for (String roleName : vo.getRoles()) {
                SysRole role = this.getAuthDao().findRoleByName(roleName);
                user.getRoleList().add(role);
            }
        }
        this.getAuthDao().saveOrUpdateUser(user);
    }

    public PageResult<SysRole> getRoleList(RoleVo vo) {
        return this.getAuthDao().getAllRoles(vo);
    }

    public void createRole(AddRoleVo vo) throws Exception {
        if (vo.getAddRoleName() == null) {
            throw new Exception("角色名不能为空！");
        }
        SysRole role = this.getAuthDao().findRoleByName(vo.getAddRoleName());
        if (role != null) {
            throw new Exception("角色名重复！");
        }
        SysRole role1 = new SysRole();
        role1.setCreateTime(new Date());
        role1.setDescription(vo.getAddDescription());
        role1.setRolename(vo.getAddRoleName());
        List<SysMyPermission> list = new ArrayList<SysMyPermission>();
        role1.setPermissionList(list);
        List<SysUser> list1 = new ArrayList<SysUser>();
        role1.setUserList(list1);
        this.getAuthDao().saveOrUpdateRole(role1);
        List<PermsAddVo> list2 = vo.getList();
        if (list2 != null)
            for (int i = 0; i < list2.size(); i++) {
                if ((list2.get(i).getDataDomain() != null && !"".equals(list2.get(i).getDataDomain())) || (list2.get(i).getDataType() != null && !"".equals(list2.get(i).getDataType())) || (list2.get(i).getOperation() != null && !"".equals(list2.get(i).getOperation()))) {
                    SysMyPermission myPermission = new SysMyPermission();
                    myPermission.setDataDomain(list2.get(i).getDataDomain());
                    myPermission.setOperation(list2.get(i).getOperation());
                    myPermission.setDataType(list2.get(i).getDataType());
                    myPermission.setRole(role1);
                    this.getAuthDao().saveOrUpdatePermission(myPermission);
                }
            }


    }

    public AddRoleVo getRoleById(Integer roleId) {
        SysRole role = this.authDao.findRoleById(roleId);
        if (role != null) {
            AddRoleVo vo = new AddRoleVo();
            vo.setRoleId(role.getId());
            vo.setAddRoleName(role.getRolename());
            vo.setAddDescription(role.getDescription());
            List<PermsAddVo> list = new ArrayList<PermsAddVo>();
            for (int i = 0; i < role.getPermissionList().size(); i++) {
                PermsAddVo permsAddVo = new PermsAddVo(role.getPermissionList().get(i).getDataType(), role.getPermissionList().get(i).getOperation(), role.getPermissionList().get(i).getDataDomain());
                list.add(permsAddVo);
            }
            vo.setList(list);
            return vo;
        } else {
            return null;
        }
    }

    public void modifyRole(AddRoleVo vo) throws Exception {
        if (vo.getAddRoleName() == null) {
            throw new Exception("角色名不能为空！");
        }
        SysRole role = this.getAuthDao().findRoleById(vo.getRoleId());
        if (role != null && !role.getId().equals(vo.getRoleId())) {
            throw new Exception("角色名重复！");
        }
        for (SysMyPermission myPermission : role.getPermissionList()) {
            this.authDao.delPermission(myPermission);
        }
        role.setDescription(vo.getAddDescription());
        role.setRolename(vo.getAddRoleName());
        try {
            this.getAuthDao().saveOrUpdateRole(role);
        } catch (Exception e) {
            e.printStackTrace();
        }

        List<PermsAddVo> list2 = vo.getList();
        if (list2 != null)
            for (int i = 0; i < list2.size(); i++) {
                if ((list2.get(i).getDataDomain() != null && !"".equals(list2.get(i).getDataDomain())) || (list2.get(i).getDataType() != null && !"".equals(list2.get(i).getDataType())) || (list2.get(i).getOperation() != null && !"".equals(list2.get(i).getOperation()))) {
                    SysMyPermission myPermission = new SysMyPermission();
                    myPermission.setDataDomain(list2.get(i).getDataDomain());
                    myPermission.setOperation(list2.get(i).getOperation());
                    myPermission.setDataType(list2.get(i).getDataType());
                    myPermission.setRole(role);
                    this.getAuthDao().saveOrUpdatePermission(myPermission);
                }
            }


    }

    public void delRole(Integer roleId) {
        SysRole role = this.authDao.findRoleById(roleId);
        for (int k = 0; k < role.getPermissionList().size(); k++) {
            this.authDao.delPermission(role.getPermissionList().get(k));
        }
        authDao.delRole(role);
    }

    public PageResult<SysMyPermission> getpermList(PermsVo vo) {
        return this.getAuthDao().getAllPerm(vo);
    }

    @Override
    public PermsVo getPermById(Integer roleId) {
        SysMyPermission permById = this.authDao.findPermById(roleId);
        PermsVo vo = new PermsVo();
        if (permById != null) {
            vo.setId(permById.getId());
            vo.setDataDomain(permById.getDataDomain());
            vo.setDataType(permById.getDataType());
            vo.setOperation(permById.getOperation());
            vo.setRoleId(permById.getRole().getId());
            vo.setDescription(permById.getRole().getDescription());
            vo.setRoleName(permById.getRole().getRolename());
        }
        return vo;
    }

    @Override
    public void updatePerm(PermsVo vo) {
        if (vo != null) {
            SysMyPermission p = new SysMyPermission();
            SysRole roleById = authDao.findRoleById(vo.getRoleId());
            p.setRole(roleById);
            p.setOperation(vo.getOperation());
            p.setDataType(vo.getDataType());
            p.setDataDomain(vo.getDataDomain());
            p.setId(vo.getId());
            authDao.saveOrUpdatePermission(p);
        }
    }

    public void delPerm(Integer id) {
        SysMyPermission permById = authDao.findPermById(id);
        authDao.delPerm(permById);
    }

    @Override
    public SysUser getUserByLoginName(String loginName) {
        return this.getAuthDao().findByName(loginName);
    }

    public final static String BUSINESS_ROOT_PATH = "/business/";

    public final static String BUSINESS_API_PATH = "/business/api／";

    @Override
    public void createGroup(String name,String moduleName, String appid, String appsecret, String descript, Date expired) {
        SysGroup group = new SysGroup();
        group.setAppid(appid);
        group.setAppSecret(appsecret);
        Date now = new Date();
        group.setCreateTime(now);
        group.setDescript(descript);
        group.setName(name);
        group.setState(GroupState.Available);
        group.setExpired(expired);
        group.setModuleName(moduleName);
        this.getAuthDao().insertGroup(group);

        //创建组的经理permission
        SysMyPermission permissionManager = new SysMyPermission();
        permissionManager.setDataType(GroupRolePrefix.Manager.getPrefix() + group.getName());
        permissionManager.setOperation("*");
        //创建组内经理角色
        SysRole roleManager = new SysRole();
        roleManager.setCreateTime(now);
        roleManager.setRolename(GroupRolePrefix.Manager.getPrefix() + group.getName());
        roleManager.setDescription("组" + group.getName() + "的经理角色");
        ArrayList<SysMyPermission> permsManager = new ArrayList<SysMyPermission>();
        permsManager.add(permissionManager);
        roleManager.setPermissionList(permsManager);

        //创建组的会员permission
        SysMyPermission permissionMember = new SysMyPermission();
        permissionMember.setDataType(GroupRolePrefix.Member.getPrefix() + group.getName());
        permissionMember.setOperation("*");
        //创建组内会员角色
        SysRole roleMember = new SysRole();
        roleMember.setCreateTime(now);
        roleMember.setRolename(GroupRolePrefix.Member.getPrefix() + group.getName());
        roleMember.setDescription("组" + group.getName() + "的会员角色");
        ArrayList<SysMyPermission> permsMember = new ArrayList<SysMyPermission>();
        permsMember.add(permissionMember);
        roleMember.setPermissionList(permsMember);

        //创建组的店长permission
        SysMyPermission permissionShopowner = new SysMyPermission();
        permissionShopowner.setDataType(GroupRolePrefix.Shopowner.getPrefix() + group.getName());
        permissionShopowner.setOperation("*");
        //创建组内店长角色
        SysRole roleShopowner = new SysRole();
        roleShopowner.setCreateTime(now);
        roleShopowner.setRolename(GroupRolePrefix.Shopowner.getPrefix() + group.getName());
        roleShopowner.setDescription("组" + group.getName() + "的店长角色");
        ArrayList<SysMyPermission> permsShopowner = new ArrayList<SysMyPermission>();
        permsShopowner.add(permissionShopowner);
        roleShopowner.setPermissionList(permsShopowner);

        //创建组的销售permission
        SysMyPermission permissionSaler = new SysMyPermission();
        permissionSaler.setDataType(GroupRolePrefix.Saler.getPrefix() + group.getName());
        permissionSaler.setOperation("*");
        //创建组内销售角色
        SysRole roleSaler = new SysRole();
        roleSaler.setCreateTime(now);
        roleSaler.setRolename(GroupRolePrefix.Saler.getPrefix() + group.getName());
        roleSaler.setDescription("组" + group.getName() + "的销售角色");
        ArrayList<SysMyPermission> permsSaler = new ArrayList<SysMyPermission>();
        permsSaler.add(permissionSaler);
        roleSaler.setPermissionList(permsSaler);

        //创建组的普通顾客permission
        SysMyPermission permissionCustomer = new SysMyPermission();
        permissionCustomer.setDataType(GroupRolePrefix.Customer.getPrefix() + group.getName());
        permissionCustomer.setOperation("*");
        //创建组内普通顾客角色
        SysRole roleCutomer = new SysRole();
        roleCutomer.setCreateTime(now);
        roleCutomer.setRolename(GroupRolePrefix.Customer.getPrefix() + group.getName());
        roleCutomer.setDescription("组" + group.getName() + "的普通顾客角色");
        ArrayList<SysMyPermission> permsCustomer = new ArrayList<SysMyPermission>();
        permsCustomer.add(permissionSaler);
        roleCutomer.setPermissionList(permsCustomer);

        this.getAuthDao().saveOrUpdateRole(roleManager);
        this.getAuthDao().saveOrUpdateRole(roleMember);
        this.getAuthDao().saveOrUpdateRole(roleShopowner);
        this.getAuthDao().saveOrUpdateRole(roleSaler);
        this.getAuthDao().saveOrUpdateRole(roleCutomer);


        permissionManager.setRole(roleManager);
        this.getAuthDao().saveOrUpdatePermission(permissionManager);
        permissionMember.setRole(roleMember);
        this.getAuthDao().saveOrUpdatePermission(permissionMember);
        permissionShopowner.setRole(roleShopowner);
        this.getAuthDao().saveOrUpdatePermission(permissionShopowner);
        permissionSaler.setRole(roleSaler);
        this.getAuthDao().saveOrUpdatePermission(permissionSaler);
        permissionCustomer.setRole(roleCutomer);
        this.getAuthDao().saveOrUpdatePermission(permissionCustomer);


        SysAuthcMap map1 = new SysAuthcMap();
        map1.setAuthcType(AuthcType.authc.name());
        map1.setUrl(BUSINESS_ROOT_PATH + group.getName() + "/**");
        this.getAuthDao().saveOrUpdateAuthcMap(map1);

        SysAuthcMap map2 = new SysAuthcMap();
        map2.setAuthcType(AuthcType.perms.name());
        map2.setUrl(BUSINESS_ROOT_PATH + group.getName() + "/" + GroupRolePrefix.Customer.getValue() + "/**");
        map2.setVal(GroupRolePrefix.Customer.getPrefix() + group.getName() + ":*:*");
        this.getAuthDao().saveOrUpdateAuthcMap(map2);

        SysAuthcMap map3 = new SysAuthcMap();
        map3.setAuthcType(AuthcType.perms.name());
        map3.setUrl(BUSINESS_ROOT_PATH + group.getName() + "/" + GroupRolePrefix.Manager.getValue() + "/**");
        map3.setVal(GroupRolePrefix.Manager.getPrefix() + group.getName() + ":*:*");
        this.getAuthDao().saveOrUpdateAuthcMap(map3);

        SysAuthcMap map4 = new SysAuthcMap();
        map4.setAuthcType(AuthcType.perms.name());
        map4.setUrl(BUSINESS_ROOT_PATH + group.getName() + "/" + GroupRolePrefix.Member.getValue() + "/**");
        map4.setVal(GroupRolePrefix.Member.getPrefix() + group.getName() + ":*:*");
        this.getAuthDao().saveOrUpdateAuthcMap(map4);

        SysAuthcMap map5 = new SysAuthcMap();
        map5.setAuthcType(AuthcType.perms.name());
        map5.setUrl(BUSINESS_ROOT_PATH + group.getName() + "/" + GroupRolePrefix.Saler.getValue() + "/**");
        map5.setVal(GroupRolePrefix.Saler.getPrefix() + group.getName() + ":*:*");
        this.getAuthDao().saveOrUpdateAuthcMap(map5);

        SysAuthcMap map6 = new SysAuthcMap();
        map6.setAuthcType(AuthcType.perms.name());
        map6.setUrl(BUSINESS_ROOT_PATH + group.getName() + "/" + GroupRolePrefix.Shopowner.getValue() + "/**");
        map6.setVal(GroupRolePrefix.Shopowner.getPrefix() + group.getName() + ":*:*");
        this.getAuthDao().saveOrUpdateAuthcMap(map6);

        SysAuthcMap map7 = new SysAuthcMap();
        map7.setAuthcType(AuthcType.perms.name());
        map7.setUrl(BUSINESS_API_PATH + group.getName() + "/" + GroupRolePrefix.Customer.getValue() + "/**");
        map7.setVal(GroupRolePrefix.Customer.getPrefix() + group.getName() + ":*:*");
        this.getAuthDao().saveOrUpdateAuthcMap(map7);

        SysAuthcMap map8 = new SysAuthcMap();
        map8.setAuthcType(AuthcType.perms.name());
        map8.setUrl(BUSINESS_API_PATH + group.getName() + "/" + GroupRolePrefix.Manager.getValue() + "/**");
        map8.setVal(GroupRolePrefix.Manager.getPrefix() + group.getName() + ":*:*");
        this.getAuthDao().saveOrUpdateAuthcMap(map8);

        SysAuthcMap map9 = new SysAuthcMap();
        map9.setAuthcType(AuthcType.perms.name());
        map9.setUrl(BUSINESS_API_PATH + group.getName() + "/" + GroupRolePrefix.Member.getValue() + "/**");
        map9.setVal(GroupRolePrefix.Member.getPrefix() + group.getName() + ":*:*");
        this.getAuthDao().saveOrUpdateAuthcMap(map9);

        SysAuthcMap map10 = new SysAuthcMap();
        map10.setAuthcType(AuthcType.perms.name());
        map10.setUrl(BUSINESS_API_PATH + group.getName() + "/" + GroupRolePrefix.Saler.getValue() + "/**");
        map10.setVal(GroupRolePrefix.Saler.getPrefix() + group.getName() + ":*:*");
        this.getAuthDao().saveOrUpdateAuthcMap(map10);

        SysAuthcMap map11 = new SysAuthcMap();
        map11.setAuthcType(AuthcType.perms.name());
        map11.setUrl(BUSINESS_API_PATH + group.getName() + "/" + GroupRolePrefix.Shopowner.getValue() + "/**");
        map11.setVal(GroupRolePrefix.Shopowner.getPrefix() + group.getName() + ":*:*");
        this.getAuthDao().saveOrUpdateAuthcMap(map11);


    }

    @Override
    public PageResult<SysGroup> getgroupList(GroupVo vo) {
        return this.getAuthDao().getAllGroups(vo);
    }

    @Override
    public void testHibernate() {
        Date now =new Date();
        YearCard yearCard=new YearCard();
        yearCard.setCreateTime(now);
        yearCard.setDescription("年卡");
        yearCard.setExpiredTime(now);
        yearCard.setName("测试年卡");
        yearCard.setSaleTime(now);
        yearCard.setTotalMoney(100f);
        this.getAuthDao().saveOrUpdateObj(yearCard);
        YogaRechargeCard yogaRechargeCard=new YogaRechargeCard();
        yogaRechargeCard.setCreateTime(now);
        yogaRechargeCard.setDescription("瑜伽充值卡");
        yogaRechargeCard.setExpiredTime(now);
        yogaRechargeCard.setName("测试瑜伽充值卡");
        yogaRechargeCard.setSaleTime(now);
        yogaRechargeCard.setTotalMoney(100f);
        yogaRechargeCard.setRestMoney(200f);
        yogaRechargeCard.setCostMoney(300f);
        yogaRechargeCard.setPersonalPrice(20.00f);
        yogaRechargeCard.setNormalPrice(21.00f);
        this.getAuthDao().saveOrUpdateObj(yogaRechargeCard);
        TimePriceCard timePriceCard=new TimePriceCard();
        timePriceCard.setCreateTime(now);
        timePriceCard.setDescription("次数单价卡");
        timePriceCard.setExpiredTime(now);
        timePriceCard.setName("测试次数单价卡");
        timePriceCard.setSaleTime(now);
        timePriceCard.setTotalMoney(100f);
        timePriceCard.setRestMoney(200f);
        timePriceCard.setCostMoney(300f);
        timePriceCard.setTotalTimes(20);
        timePriceCard.setRestTimes(13);
        timePriceCard.setCostTimes(7);
        timePriceCard.setPrice(24.34f);
        this.getAuthDao().saveOrUpdateObj(timePriceCard);
    }

    @Override
    public SysGroup getGroupByName(String name) {
        return this.getAuthDao().getGroupByName(name);
    }
}
